package multidraw.model;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Ellipse2D;
import java.io.Serializable;
import java.util.Vector;

//In the light of Factory pattern
public abstract class Shape implements Serializable {
	protected long shapeID;
		
	Color penColor;
	
	final static double DISTANCE_EPS = 4;

	final static float dash1[] = { 10.0f };
	final static BasicStroke dashed = new BasicStroke(1.0f,
			BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
	
	public abstract void draw(Graphics g, boolean selected);
	
	public abstract void drawOutline(Graphics g);
	
	public boolean isNearControlPoint(Point p) {
		Vector<Point> controlPointList = getControlPoints();
		for (int i = 0; i < controlPointList.size(); i++) {
			if (p.distance(controlPointList.get(i)) < DISTANCE_EPS ) {
				return true;
			}
		}
		return false;
	}
	
	//for hightlighting selected objects.
	public void drawControlPoints(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		
		Color oldColor = g2.getColor();
		
		g2.setColor(Color.yellow);
		
		Vector<Point> cp = getControlPoints();
		
		
		for (Point p: cp) {
			//draw a circle at these control points
			Ellipse2D circ = new Ellipse2D.Double(p.getX() - DISTANCE_EPS, 
					p.getY() - DISTANCE_EPS, 2 * DISTANCE_EPS, 2 * DISTANCE_EPS);
			g2.fill(circ);
			//g2.fillOval(x, y, width, height)
		}
		g2.setColor(oldColor);
	}
	
	public abstract boolean isInsideSelectionalArea(int X, int Y);

	public Color getPenColor() {
		return penColor;
	}
	
	public void setPenColor(Color c) {
		this.penColor = c;
	}
	
	
	
	/**
	 * Check if the point P near a corner of the shape.
	 * @param p
	 * @return
	 */
	//public boolean isNearBoundaryCorner(Point p);
	
	//public 
	
	public abstract Shape getOutlineShape();
	
	public abstract void translate(Point p1, Point p2);
	
	protected abstract Vector<Point> getControlPoints();
	
	public void switchFilling()
	{		
	}
	
	public long getShapeID() {
		return shapeID;
	}
}
